package org.fluidripple.socket.operation;

import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.util.concurrent.GenericFutureListener;
import lombok.extern.slf4j.Slf4j;
import org.fluidripple.socket.session.Session;
import org.fluidripple.socket.session.SessionManager;
import org.fluidripple.socket.stickhalf.FixedLengthDecoderImpl;


import java.util.Objects;


@Slf4j
public class ChannelOperation {

    public static void closeChannel(Channel channel, GenericFutureListener listener) {
        log.info("连接断开");
        Session sessionOld = SessionManager.getSession(channel);
        channel.close();
        SessionManager.inactive(sessionOld);
        AutomationOperation.delete(channel);
    }

    public static void addAfterChannelHandler(Channel channel,String preHandlerName,String name, ChannelHandler handler){
        ChannelHandler channelHandler = getChannelHandler(channel, FixedLengthDecoderImpl.name);
        if (Objects.nonNull(channelHandler)){
            return;
        }
        ChannelPipeline pipeline = channel.pipeline();
        /**
         * 在preHandlerName之后，增加一个名称为name的handler处理器
         */
        pipeline.addAfter(preHandlerName,name,handler);
    }

    public static void removeChannelHandler(Channel channel,String name){
        ChannelPipeline pipeline = channel.pipeline();
        if (pipeline.get(name) != null){
            /**
             * 删除指定名称的处理器
             */
            pipeline.remove(name);
        }
    }

    public static ChannelHandler getChannelHandler(Channel channel,String name){
        ChannelPipeline pipeline = channel.pipeline();
        /**
         * 获取指定名称的处理器
         */
        ChannelHandler handler = pipeline.get(name);
        return handler;
    }

    public static void replaceChannelHandler(Channel channel,String preHandlerName,String name, ChannelHandler handler){
        ChannelPipeline pipeline = channel.pipeline();
        ChannelHandler oldHandler = pipeline.get(name);
        if (Objects.isNull(oldHandler)){
            pipeline.addAfter(preHandlerName,name,handler);
            return;
        }
        /**
         * 替换老的处理器，改成新的处理器对象
         */
        pipeline.replace(oldHandler,name,handler);
    }

    public static void writer(Channel channel, ByteBuf buf, WriterFunction function) throws InterruptedException {
        ChannelFuture future = channel.writeAndFlush(buf);
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                boolean success = channelFuture.isSuccess();
                if (success){
                    function.apply();
                }
            }
        });
        future.sync();
    }

    @FunctionalInterface
    public interface WriterFunction{
        public void apply();
    }
}
